package com.school.sports.config;

import com.school.sports.service.ExceptionHandlingService;
import com.school.sports.service.ExceptionNotificationService;
import com.school.sports.util.DatabaseConnectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;

/**
 * 异常处理配置类
 * 配置异常处理相关的定时任务和系统配置
 */
@Slf4j
@Configuration
@EnableScheduling
public class ExceptionHandlingConfig {

    @Autowired(required = false)
    private ExceptionHandlingService exceptionHandlingService;

    @Autowired(required = false)
    private ExceptionNotificationService exceptionNotificationService;

    @Autowired(required = false)
    private DatabaseConnectionUtil databaseConnectionUtil;

    private boolean databaseAvailable = false;

    /**
     * 定时清理过期的异常记录
     * 每天凌晨2点执行，清理30天前已处理的异常记录
     */
    @Scheduled(cron = "0 0 2 * * ?")
    @ConditionalOnProperty(name = "exception.scheduling.enabled", havingValue = "true", matchIfMissing = true)
    public void cleanExpiredExceptionRecords() {
        // 检查数据库连接状态
        if (!isDatabaseAvailable()) {
            log.warn("数据库不可用，跳过清理过期异常记录任务");
            return;
        }

        if (exceptionHandlingService == null) {
            log.warn("异常处理服务未初始化，跳过清理过期异常记录任务");
            return;
        }

        try {
            log.info("开始清理过期的异常记录");

            // 清理30天前已处理的异常记录
            LocalDateTime beforeTime = LocalDateTime.now().minusDays(30);
            int cleanedCount = exceptionHandlingService.cleanExpiredExceptionRecords(beforeTime);

            log.info("清理过期异常记录完成，共清理{}条记录", cleanedCount);

            // 如果清理了记录，发送通知给管理员
            if (cleanedCount > 0) {
                String title = "异常记录清理通知";
                String content = String.format("系统已清理%d条30天前的已处理异常记录", cleanedCount);
                // 这里可以调用消息服务发送通知
            }
        } catch (Exception e) {
            log.error("清理过期异常记录失败：{}", e.getMessage(), e);
        }
    }

    /**
     * 定时检查待处理的严重异常
     * 每10分钟执行一次，检查是否有超过1小时未处理的严重异常
     */
    @Scheduled(fixedRate = 600000) // 10分钟
    @ConditionalOnProperty(name = "exception.scheduling.enabled", havingValue = "true", matchIfMissing = true)
    public void checkUnhandledSevereExceptions() {
        // 检查数据库连接状态
        if (!isDatabaseAvailable()) {
            log.debug("数据库不可用，跳过检查未处理的严重异常任务");
            return;
        }

        if (exceptionHandlingService == null) {
            log.debug("异常处理服务未初始化，跳过检查未处理的严重异常任务");
            return;
        }

        try {
            log.debug("检查未处理的严重异常");

            // 检查是否有超过1小时未处理的严重异常
            long severeCount = exceptionHandlingService.getSevereExceptionCount();
            long pendingCount = exceptionHandlingService.getPendingExceptionCount();

            if (severeCount > 0 || pendingCount > 0) {
                log.warn("发现{}个严重异常，{}个待处理异常", severeCount, pendingCount);

                // 可以在这里发送提醒通知
                if (severeCount > 0) {
                    sendSevereExceptionReminder(severeCount);
                }
            }
        } catch (Exception e) {
            log.error("检查未处理的严重异常失败：{}", e.getMessage(), e);
            // 设置数据库不可用标志，避免频繁尝试
            databaseAvailable = false;
        }
    }

    /**
     * 定时生成异常统计报告
     * 每天上午9点执行，生成前一天的异常统计报告
     */
    @Scheduled(cron = "0 0 9 * * ?")
    @ConditionalOnProperty(name = "exception.scheduling.enabled", havingValue = "true", matchIfMissing = true)
    public void generateDailyExceptionReport() {
        // 检查数据库连接状态
        if (!isDatabaseAvailable()) {
            log.warn("数据库不可用，跳过生成每日异常统计报告");
            return;
        }

        if (exceptionHandlingService == null || exceptionNotificationService == null) {
            log.warn("异常处理相关服务未初始化，跳过生成每日异常统计报告");
            return;
        }

        try {
            log.info("开始生成每日异常统计报告");

            LocalDateTime endTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
            LocalDateTime startTime = endTime.minusDays(1);

            // 生成报告
            Object reportData = exceptionHandlingService.generateExceptionReport(startTime, endTime, "daily");

            // 发送报告通知
            exceptionNotificationService.sendExceptionStatisticsReport(reportData, "日报");

            log.info("每日异常统计报告生成完成");
        } catch (Exception e) {
            log.error("生成每日异常统计报告失败：{}", e.getMessage(), e);
        }
    }

    /**
     * 每周生成异常统计报告
     * 每周一上午9点执行，生成上一周的异常统计报告
     */
    @Scheduled(cron = "0 0 9 ? * MON")
    @ConditionalOnProperty(name = "exception.scheduling.enabled", havingValue = "true", matchIfMissing = true)
    public void generateWeeklyExceptionReport() {
        // 检查数据库连接状态
        if (!isDatabaseAvailable()) {
            log.warn("数据库不可用，跳过生成每周异常统计报告");
            return;
        }

        if (exceptionHandlingService == null || exceptionNotificationService == null) {
            log.warn("异常处理相关服务未初始化，跳过生成每周异常统计报告");
            return;
        }

        try {
            log.info("开始生成每周异常统计报告");

            LocalDateTime endTime = LocalDateTime.now();
            // 计算上周的开始时间（周一0点）
            LocalDateTime startTime = endTime.minusWeeks(1).withHour(0).withMinute(0).withSecond(0);

            // 生成报告
            Object reportData = exceptionHandlingService.generateExceptionReport(startTime, endTime, "weekly");

            // 发送报告通知
            exceptionNotificationService.sendExceptionStatisticsReport(reportData, "周报");

            log.info("每周异常统计报告生成完成");
        } catch (Exception e) {
            log.error("生成每周异常统计报告失败：{}", e.getMessage(), e);
        }
    }

    /**
     * 每月生成异常统计报告
     * 每月1号上午9点执行，生成上个月的异常统计报告
     */
    @Scheduled(cron = "0 0 9 1 * ?")
    @ConditionalOnProperty(name = "exception.scheduling.enabled", havingValue = "true", matchIfMissing = true)
    public void generateMonthlyExceptionReport() {
        // 检查数据库连接状态
        if (!isDatabaseAvailable()) {
            log.warn("数据库不可用，跳过生成每月异常统计报告");
            return;
        }

        if (exceptionHandlingService == null || exceptionNotificationService == null) {
            log.warn("异常处理相关服务未初始化，跳过生成每月异常统计报告");
            return;
        }

        try {
            log.info("开始生成每月异常统计报告");

            LocalDateTime endTime = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
            LocalDateTime startTime = endTime.minusMonths(1);

            // 生成报告
            Object reportData = exceptionHandlingService.generateExceptionReport(startTime, endTime, "monthly");

            // 发送报告通知
            exceptionNotificationService.sendExceptionStatisticsReport(reportData, "月报");

            log.info("每月异常统计报告生成完成");
        } catch (Exception e) {
            log.error("生成每月异常统计报告失败：{}", e.getMessage(), e);
        }
    }

    /**
     * 发送严重异常提醒
     */
    private void sendSevereExceptionReminder(long severeCount) {
        try {
            String title = "严重异常处理提醒";
            String content = String.format("系统当前有%d个严重异常未处理，请及时处理", severeCount);

            // 这里可以调用消息服务发送通知给管理员
            // messageService.sendMessageToRoles(title, content, "紧急通知", new String[]{"管理员", "系统管理员"});

            log.info("已发送严重异常处理提醒，{}个严重异常待处理", severeCount);
        } catch (Exception e) {
            log.error("发送严重异常提醒失败：{}", e.getMessage(), e);
        }
    }

    /**
     * 检查数据库是否可用
     *
     * @return 数据库可用状态
     */
    private boolean isDatabaseAvailable() {
        // 如果上次检查已经确定数据库可用，并且距离上次检查时间不到1分钟，直接返回
        if (databaseAvailable && databaseConnectionUtil != null) {
            return true;
        }

        // 尝试重新检查数据库连接
        if (databaseConnectionUtil != null) {
            try {
                String status = databaseConnectionUtil.getDatabaseStatus();
                databaseAvailable = status.contains("连接正常");
                if (databaseAvailable) {
                    log.debug("数据库连接检查通过");
                } else {
                    log.warn("数据库连接检查失败: {}", status);
                }
            } catch (Exception e) {
                log.warn("数据库连接检查异常: {}", e.getMessage());
                databaseAvailable = false;
            }
        } else {
            // 如果数据库连接工具未初始化，假设数据库不可用
            databaseAvailable = false;
            log.debug("数据库连接工具未初始化");
        }

        return databaseAvailable;
    }
}